#include "physics/pobject.h"
#include "physics/pworld.h"

#include <QDomElement>
#include <QRegExp>

static const QRegExp NAME = QRegExp(".*_");
static const QRegExp TYPE = QRegExp("_.*");

PObject::PObject(PWorld *world, QString name) :
    QObject(world)
{
    myWorld = world;
    myPos = PVector();
    myV = PVector();
    myA = PVector();
    myM = 10;
    myR = 10;

    myName = "object";
    myLife = 100;
    myDamage = 100;

    myBrightness = 0;

    if (name != "") {
        myName = name;
    } else {
        myName = QString("obj-%1").arg(world->getObjects().size() + 1);
    }
}

PObject::~PObject() {

}


double PObject::distanceTo(PObject *o) {
    return myPos.distance(o->myPos);
}

double PObject::distanceSqrTo(PObject *o) {
    return myPos.distanceSqr(o->myPos);
}


PVector PObject::getPos() const {
    return myPos;
}

PVector PObject::getV() const {
    return myV;
}

double PObject::getM() const {
    return myM;
}

double PObject::getR() const {
    return myR;
}

PWorld *PObject::getWorld() const {
    return myWorld;
}

double PObject::getX() const {
    return myPos.getX();
}

double PObject::getY() const {
    return myPos.getY();
}

void PObject::setPos(PVector pos) {
    myPos = pos;
}

void PObject::setPos(double x, double y) {
    myPos = PVector(x, y);
}

void PObject::setV(PVector v) {
    myV = v;
}

void PObject::setV(double x, double y) {
    myV = PVector(x, y);
}

void PObject::setM(double m) {
    myM = m;
}

void PObject::setR(double r) {
    myR = r;
}

PVector PObject::getA() const {
    return myA;
}

void PObject::setA(PVector a) {
    myA = a;
}

void PObject::move(double t) {
    myV = myV +  myA * t;
    myPos = myPos + myV * t;
}

void PObject::setLife(int life) {
    myLife = life;
}

int PObject::getLife() const {
    return myLife;
}

int PObject::getDamage() const {
    return myDamage;
}

void PObject::setDamage(int damage) {
    myDamage = damage;
}

void PObject::hit(PObject *obj) {
    myLife -= obj->myDamage;
    obj->myLife -= myDamage;
}

int PObject::getBrightness() const {
    return myBrightness;
}

void PObject::setBrightness(int brightness) {
    myBrightness = brightness;
}

QString PObject::getName() const {
    QString str = myName;
    return str.replace(NAME, "");
}

QString PObject::getType() const {
    QString str = myName;
    return str.replace(TYPE, "");
}

void PObject::decLife(int life) {
    myLife -= life;
}

void PObject::serialize(QDomDocument *doc, QDomElement *e) const {
    QDomElement pos = doc->createElement("Pos");
    myPos.serialize(doc, &pos);
    e->appendChild(pos);

    QDomElement v = doc->createElement("V");
    myV.serialize(doc, &v);
    e->appendChild(v);

    QDomElement m = doc->createElement("M");
    QDomNode m_v = doc->createTextNode(QString("%1").arg(myM));
    m.appendChild(m_v);
    e->appendChild(m);

    QDomElement r = doc->createElement("R");
    QDomNode r_v = doc->createTextNode(QString("%1").arg(myR));
    r.appendChild(r_v);
    e->appendChild(r);

    QDomElement name = doc->createElement("Name");
    QDomNode name_v = doc->createTextNode(QString("%1").arg(myName));
    name.appendChild(name_v);
    e->appendChild(name);

    QDomElement life = doc->createElement("Life");
    QDomText life_v = doc->createTextNode(QString("%1").arg(myLife));
    life.appendChild(life_v);
    e->appendChild(life);

    QDomNode damage = doc->createElement("Damage");
    QDomNode damage_v = doc->createTextNode(QString("%1").arg(myDamage));
    damage.appendChild(damage_v);
    e->appendChild(damage);

    QDomNode brightness = doc->createElement("Brightness");
    QDomNode brightness_v = doc->createTextNode(QString("%1").arg(myBrightness));
    brightness.appendChild(brightness_v);
    e->appendChild(brightness);
}

PObject *PObject::deserialize(QDomNode *e, PWorld *parent) {
    PVector pos;
    PVector v;
    double m = 0;
    double r = 0;
    QString name;
    int life = 0;
    int damage = 0;
    int brightness = 0;
    QDomNode node = e->firstChild();
    while (!node.isNull()) {
        if (!node.isNull()) {
            QDomElement elem = node.toElement();
            QString tname = elem.tagName();
            if (tname == "Pos") {
                pos = PVector::deserialize(elem);
            } else if (tname == "V") {
                v = PVector::deserialize(elem);
            } else if (tname == "M") {
                QDomNode mass = elem.firstChild();
                if (mass.isNull()) {
                    return 0;
                }
                m = mass.toText().data().toDouble();
            } else if (tname == "R") {
                r = elem.firstChild().toText().data().toDouble();
            } else if (tname == "Name") {
                name = elem.firstChild().toText().data();
            } else if (tname == "Life") {
                life = elem.firstChild().toText().data().toInt();
            } else if (tname == "Damage") {
                damage = elem.firstChild().toText().data().toInt();
            } else if (tname == "Brightness") {
                brightness = elem.firstChild().toText().data().toInt();
            }
        }
        node = node.nextSibling();
    }

    PObject *object = new PObject(parent, name);
    object->myPos = pos;
    object->myV = v;
    object->myM = m;
    object->myR = r;
    object->myName = name;
    object->myLife = life;
    object->myDamage = damage;
    object->myBrightness = brightness;
    return object;
}
